在介紹 useContext 之前,得先介紹 Context。Context是 React 用來處理資料全域共享的一個 API,它還可以避免需要多層傳遞 props 的情況,或是元件之間沒有上下層關係的情況。使用 Context 主要是透過以下幾個步驟
React.createContext() 創建 Context 物件。React.createContext() 裡面可以傳遞參數。const Context = React.createContext()
Context 上面會有一個 Provider 元件,接著我們就使用 Context.Provider 來包覆元件,並傳遞一個 value。我們先將資料透過 value 傳遞給 Provider,Provider 再將資料傳給裡面的元件,如 TestComponent1 及 TestComponent2。下面的例子中,建立 Context 的根元件是 UserProfile
const Context = React.createContext({ count: 1 })
class UserProfile extends React.Component {
state = {
count: 0
}
render() {
return (
<div>
<Context.Provider value={ this.state.count }>
<TestComponent1 />
<TestComponent2 />
</Context.Provider>
</div>
);
}
}
Context.Consumer 獲得 Context 共享的資料。// TestComponent1 元件
class TestComponent1 extends React.Component {
render () {
return <Context.Consumer>
{count => <div> { count } </div>}
</Context.Consumer>
}
}
// TestComponent2 元件
class TestComponent2 extends React.Component {
render () {
return <Context.Consumer>
{count => <button onClick={ count => count + 1}>count++</button>}
</Context.Consumer>
}
}
不過這種在元件內直接建立 Context 的方式,容易造成元件比較混亂,所以通常會在獨立的檔案中建立 Context,之後再由根元件調用,後面將會有範例。需要注意的是,盡量一個 Context 只給一個狀態,不要包裝太多狀態,會讓狀態不好管理。
useContext(Context) 基本上就是為了讓我們使用 Context 所提出的 API,它接受 React.createContext() 的返回值作為參數,返回最新的 Context。另外,使用 useContext(context) 就不用再去使用 Provider、Consumer。例如下面的範例,我們透過 React.createContext() 建立資料後,就可以賦給 Context,之後再利用 useContext(Context) 在元件中調用 Context 就可以拿到裡面的資料。
const Context = React.createContext({ loading: false, name: 'leo'})
// 元件 1
const TestComponentOne = () => {
const context = useContext(Context)
return <div>
{ context.loading && 'loading...' }
</div>
}
// 元件 2
const TestComponentTwo = () => {
const context = useContext(Context)
return <div>
{ context.name && context.name }
</div>
}
我們也可以利用直接 export Context 的方式來傳遞,如下
export const Context = React.createContext({ loading: false, name: 'leo'})
然後在元件內 import
import { Context } from './index'
const TestComponentOne = () => {
const context = useContext(Context)
return <div>
{ context.loading && 'loading...' }
</div>
}
不過,這種做法並不是比較好的方法。比較好的方式是建立一個單獨的模組來封裝 Context。我們在 src 內創建一個 store 資料夾並建立一支 index.js 檔,將 Context 移到裡面,如下
import React from 'react'
const Context = React.createContext({ loading: false, name: 'leo'})
export default Context
然後在其他元件引入
import Context from '../../store'
const TestComponentOne = () => {
const context = useContext(Context)
return <div>
{ context.loading && 'loading...' }
</div>
}
上下文(Context)
[React] React Context API 以及 useContext Hook 的使用
這麼好的文章,希望更多人看到!!!
大大解釋得很清楚
原本對於useContext是一竅不通,但是看到const context= useContext(Context)這邊,
直接了解。